#include "ObjectEntity.h"
#include "DatabaseAccessObject.h"

void FeedObject::PopulateFromEntity( RawEntityFeed& rawEntity )
{
    m_id = rawEntity.id.GetValue<int>();
    m_name = rawEntity.name.GetPointer<char>();
    m_pnacPrefix = rawEntity.pnacprefix.GetPointer<char>();
    m_attribution = rawEntity.attributioin.GetPointer<char>();
    m_alertStatus = rawEntity.alertstatus.GetValue<int>();
    m_emailList = rawEntity.emaillist.GetPointer<char>();
}

void FeedObject::UpdateToDataBase( DataBaseAccessObject& dao )
{
    RawEntityFeed rawEntity;
    rawEntity.id.SetValue<int>( m_id );
    rawEntity.alertstatus.SetValue<int>( m_alertStatus );
    dao.UpdateFeedStatus( &rawEntity );
}

void RuleObject::PopulateFromEntity( RawEntityRule& rawEntity )
{
   
}

void FeedRuleObject::PopulateFromEntity( RawEntityFeedRule& rawEntity )
{
    m_id             = rawEntity.id.GetValue<int>();
    m_feedId         = rawEntity.feedID.GetValue<int>();
    m_ruleId         = rawEntity.ruleID.GetValue<int>();
    m_value          = rawEntity.value.GetPointer<char>();
    m_alertStatus    = rawEntity.alertStatus.GetValue<int>();
}

void FeedRuleObject::UpdateToDataBase( DataBaseAccessObject& dao )
{
    RawEntityFeedRule rawEntity;
    rawEntity.id.SetValue<int>( m_id );
    rawEntity.alertStatus.SetValue<int>( m_alertStatus );
    dao.UpdateFeedRuleStatus( &rawEntity );
}

void AlertObject::PopulateFromEntity( RawEntityAlert& rawEntity )
{
    m_id            = rawEntity.id.GetValue<int>();
    m_feedRuleId    = rawEntity.feedRuleId.GetValue<int>();
    m_message       = rawEntity.message.GetPointer<char>();
    m_flag          = rawEntity.flag.GetValue<int>();
    m_alertStatus   = rawEntity.alertstatus.GetValue<int>();

    //Retrieve datetime
    tagTIMESTAMP_STRUCT* timeStampPtr = rawEntity.createTime.GetPointer<tagTIMESTAMP_STRUCT>();
    m_createTime = boost::posix_time::ptime( 
        boost::gregorian::date( timeStampPtr->year, timeStampPtr->month, timeStampPtr->day ),
        boost::posix_time::time_duration( timeStampPtr->hour, timeStampPtr->minute, timeStampPtr->second ) );
}

void AlertObject::UpdateToDataBase( DataBaseAccessObject& dao )
{
    RawEntityAlert rawEntity;
    rawEntity.id.SetValue<int>( m_id );
    rawEntity.flag.SetValue<int>( m_flag );
    dao.UpdateAlertFlag( &rawEntity );
}

void EntityManager::GetFullFeedRuleAlertList( DataBaseAccessObject& dao, std::list< FeedObject* >& feedObjectList )
{
    //This function will retrieve and store all information for one notification generation
    //including feedlist, feedrule list, alert list etc.

    //The output will be stored in feedList, which only contains raw pointers, but real object 
    //will stored inside the entitymanager, when needs to reset, call Reset of the manager

    std::vector<RawEntityAlert> alertList;
    std::vector<RawEntityFeed>  feedList;
    std::vector<RawEntityFeedRule> feedRuleList;
    std::vector<RawEntityRule>  ruleList;

    dao.QueryFeedList( feedList ); //Get feedList
    dao.QueryAlertList( alertList ); //Get alertList
    dao.QueryFeedRuleValidList( feedRuleList ); //Get feedRuleList

    std::list< FeedRuleObject* > feedRuleObList;
    //Now we have everything, convert feedRuleRawList to feedRuleObjectList
    for( auto frIt = feedRuleList.begin(); frIt != feedRuleList.end(); ++frIt )
    {
        FeedRuleObject* feedRuleObject = CreateObject< FeedRuleObject >();
        feedRuleObject->PopulateFromEntity( *frIt );

        //Get all alert attached to this feedRule
        for( auto alIt = alertList.begin(); alIt != alertList.end(); )
        {
            if( alIt->feedRuleId.GetValue<int>() == feedRuleObject->m_id )
            {
                //Create a alertObject and push it into feedruleObject
                AlertObject* alertObject = CreateObject<AlertObject>();
                alertObject->PopulateFromEntity( *alIt );

                feedRuleObject->m_alerts.push_back( alertObject );

                alIt = alertList.erase( alIt );
                continue;
            }
            ++alIt;
        }

        feedRuleObList.push_back( feedRuleObject );
    }

    //Now fill feerulelist into feed
    for( auto feedIt = feedList.begin(); feedIt != feedList.end(); ++feedIt )
    {
        FeedObject* feedObject = CreateObject< FeedObject >();
        feedObject->PopulateFromEntity( *feedIt );

        //go through the feed rule list and fetch 
        for( auto feedruleit = feedRuleObList.begin(); feedruleit != feedRuleObList.end();  )
        {
            if( (*feedruleit)->m_feedId == feedObject->m_id )
            {
                feedObject->m_feedRules.push_back( *feedruleit );
                feedruleit = feedRuleObList.erase( feedruleit );
                continue;
            }
            ++feedruleit;
        }

        feedObjectList.push_back( feedObject );
    }
   
    
}